
#include <QDebug>
#include <QDir>
#include <QProcess>
#include <QThread>
#include <QWindow>

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "utils.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    embedded = true;
    window = nullptr;
    container = nullptr;
    filter = new EventFilter(this);

    ui->lineEdit->installEventFilter(filter);

    connect(ui->radioButton_GtkGUI, SIGNAL(toggled(bool)), this, SLOT(radioButton_toggled(bool)));
    connect(ui->radioButton_QtGUI, SIGNAL(toggled(bool)), this, SLOT(radioButton_toggled(bool)));

    worker = new QProcess;
    connect(worker, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(worker_state_changed(QProcess::ProcessState)));
    connect(worker, SIGNAL(readyReadStandardOutput()), this, SLOT(worker_ready_read_stdout()));
    connect(worker, SIGNAL(readyReadStandardError()), this, SLOT(worker_ready_read_stderr()));

    /* Load Default */
    ui->checkBox->setChecked(true);
    ui->radioButton_QtGUI->setChecked(true);
}

MainWindow::~MainWindow()
{
    if (worker) {
        if (worker->state() != QProcess::NotRunning) {
            worker->terminate();
        }
        delete worker;
        worker = nullptr;
    }

    delete filter;
    delete window;
    delete container;
    delete ui;
}

void MainWindow::on_checkBox_toggled(bool checked)
{
    embedded = checked;
}

void MainWindow::on_radioButton_QtGUI_toggled(bool checked)
{
    ui->radioButton_GtkGUI->setChecked(!checked);
    ui->radioButton_QtGUI->setChecked(checked);
    workname = "app-qt";
}

void MainWindow::on_radioButton_GtkGUI_toggled(bool checked)
{
    ui->radioButton_GtkGUI->setChecked(checked);
    ui->radioButton_QtGUI->setChecked(!checked);
    workname = "app-gtk";
}

void MainWindow::on_pushButton_clicked()
{
    DEBUG() << "Start a GUI Children";

    QString GuiApp;
    QStringList Args;
    QDir dir = QDir::current();
    if (dir.exists(workname)){
        GuiApp = QDir::toNativeSeparators(dir.filePath(workname));
    } else {
        qCritical() << "Cannot find Child GUI Application!";
        return;
    }

    if (!GuiApp.isEmpty()) {
        worker->start(GuiApp, Args);
    }
}

void MainWindow::worker_state_changed(QProcess::ProcessState newState)
{
    DEBUG() << "State:" << newState;

    switch (newState) {
    case QProcess::NotRunning:
        ui->pushButton->setEnabled(true);
        if (ui->stackedWidget->count() >= 0) {
            ui->stackedWidget->removeWidget(ui->stackedWidget->currentWidget());
        }
        break;
    case QProcess::Starting:
        ui->pushButton->setEnabled(false);
        break;
    case QProcess::Running:
        break;
    default:
        break;
    }
}

void MainWindow::worker_ready_read_stdout()
{
    QString output = worker->readAllStandardOutput().constData();
    QStringList lines = output.split("\n");
    for (const QString &line : qAsConst(lines)) {
        if (line.isEmpty()) continue;
        qDebug() << "===== SubProcess ===== stdout:" << line;
    }

    if (output.startsWith("X_WINDOW_ID") && output.contains("=")) {
        QStringList items = output.split("=");
        if (items.size() == 2) {
            QString s_hWnd = items.at(1);
            hWnd = s_hWnd.toInt(nullptr, 16);
            ui->lineEdit->setText("Child GUI X_WINDOW_ID is " + s_hWnd);
        }
    }

    DEBUG() << "Child GUI X_WINDOW_ID:" << QString::number(hWnd, 16);

    window = QWindow::fromWinId(hWnd);
    window->installEventFilter(filter);
    if (embedded) {
        container = QWidget::createWindowContainer(window, this, Qt::FramelessWindowHint);
        container->setAttribute(Qt::WA_NativeWindow, true);
        container->setAcceptDrops(true);
        ui->stackedWidget->addWidget(container);

        DEBUG() << "Container acceptDrops:" << container->acceptDrops();
        DEBUG() << "Container Geometry:" << container->geometry();
    } else {
        window->setFlag(Qt::WindowStaysOnTopHint, true);
        window->show();
    }
}

void MainWindow::worker_ready_read_stderr()
{
    QString output = worker->readAllStandardError().constData();
    QStringList lines = output.split("\n");
    for (const QString &line : qAsConst(lines)) {
        if (line.isEmpty()) continue;
        qDebug() << "===== SubProcess ===== stderr:" << line;
    }
}
